<template>
  <div class="stats-card" :class="{ 'loading': loading }">
    <div class="stats-icon">
      <n-icon :size="32" :color="iconColor">
        <component :is="iconComponent" />
      </n-icon>
    </div>
    
    <div class="stats-content">
      <div class="stats-value">
        <n-number-animation
          ref="numberAnimationInstRef"
          :from="0"
          :to="value"
          :duration="1500"
          :precision="precision"
          show-separator
        />
        <span v-if="suffix" class="stats-suffix">{{ suffix }}</span>
      </div>
      
      <div class="stats-label">{{ label }}</div>
      
      <div v-if="change !== undefined" class="stats-change" :class="changeClass">
        <n-icon :size="14">
          <svg v-if="change > 0" xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24">
            <path fill="currentColor" d="M16 6l2.29 2.29l-4.88 4.88l-4-4L2 16.59L3.41 18l6-6l4 4l6.3-6.29L22 12V6z"/>
          </svg>
          <svg v-else-if="change < 0" xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24">
            <path fill="currentColor" d="M16 18l2.29-2.29l-4.88-4.88l-4 4L2 7.41L3.41 6l6 6l4-4l6.3 6.29L22 12v6z"/>
          </svg>
          <svg v-else xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24">
            <path fill="currentColor" d="M19 13H5v-2h14v2z"/>
          </svg>
        </n-icon>
        <span>{{ Math.abs(change) }}%</span>
      </div>
    </div>
    
    <div v-if="loading" class="stats-loading">
      <n-skeleton height="20px" width="60%" />
      <n-skeleton height="14px" width="40%" style="margin-top: 8px;" />
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, h } from 'vue'

interface Props {
  label: string
  value: number
  suffix?: string
  change?: number
  icon: string
  iconColor?: string
  loading?: boolean
  precision?: number
}

const props = withDefaults(defineProps<Props>(), {
  iconColor: 'var(--n-color-primary)',
  loading: false,
  precision: 0
})

// 图标组件映射
const iconComponents = {
  database: () => h('svg', { xmlns: 'http://www.w3.org/2000/svg', width: '32', height: '32', viewBox: '0 0 24 24' }, [
    h('path', { fill: 'currentColor', d: 'M12 3C7.58 3 4 4.79 4 7s3.58 4 8 4s8-1.79 8-4s-3.58-4-8-4zM4 9v3c0 2.21 3.58 4 8 4s8-1.79 8-4V9c0 2.21-3.58 4-8 4s-8-1.79-8-4zm0 5v3c0 2.21 3.58 4 8 4s8-1.79 8-4v-3c0 2.21-3.58 4-8 4s-8-1.79-8-4z' })
  ]),
  heart: () => h('svg', { xmlns: 'http://www.w3.org/2000/svg', width: '32', height: '32', viewBox: '0 0 24 24' }, [
    h('path', { fill: 'currentColor', d: 'M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5C2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3C19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z' })
  ]),
  trending_up: () => h('svg', { xmlns: 'http://www.w3.org/2000/svg', width: '32', height: '32', viewBox: '0 0 24 24' }, [
    h('path', { fill: 'currentColor', d: 'M16 6l2.29 2.29l-4.88 4.88l-4-4L2 16.59L3.41 18l6-6l4 4l6.3-6.29L22 12V6z' })
  ]),
  trending_down: () => h('svg', { xmlns: 'http://www.w3.org/2000/svg', width: '32', height: '32', viewBox: '0 0 24 24' }, [
    h('path', { fill: 'currentColor', d: 'M16 18l2.29-2.29l-4.88-4.88l-4 4L2 7.41L3.41 6l6 6l4-4l6.3 6.29L22 12v6z' })
  ]),
  users: () => h('svg', { xmlns: 'http://www.w3.org/2000/svg', width: '32', height: '32', viewBox: '0 0 24 24' }, [
    h('path', { fill: 'currentColor', d: 'M16 4c0-1.11.89-2 2-2s2 .89 2 2s-.89 2-2 2s-2-.89-2-2zm4 18v-6h2.5l-2.54-7.63A1.5 1.5 0 0 0 18.54 8H17c-.8 0-1.54.37-2.01.99l-2.54 3.38c-.36.48-.85.63-1.45.63s-1.09-.15-1.45-.63L7.01 8.99C6.54 8.37 5.8 8 5 8H3.46c-.81 0-1.42.68-1.42 1.37L4.5 16H7v6h2v-6h2v6h2v-6h2v6h3z' })
  ])
}

const iconComponent = computed(() => {
  return iconComponents[props.icon as keyof typeof iconComponents] || iconComponents.database
})

const changeClass = computed(() => {
  if (props.change === undefined) return ''
  if (props.change > 0) return 'positive'
  if (props.change < 0) return 'negative'
  return 'neutral'
})
</script>

<style scoped>
.stats-card {
  position: relative;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 24px;
  background: var(--n-color-target);
  border-radius: 12px;
  border: 1px solid var(--n-border-color);
  transition: all 0.3s ease;
  overflow: hidden;
}

.stats-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
}

.stats-card.loading {
  pointer-events: none;
}

.stats-icon {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 64px;
  height: 64px;
  background: var(--n-color-primary-suppl);
  border-radius: 12px;
  opacity: 0.8;
}

.stats-content {
  flex: 1;
  min-width: 0;
}

.stats-value {
  display: flex;
  align-items: baseline;
  gap: 4px;
  font-size: 28px;
  font-weight: 700;
  color: var(--n-text-color-1);
  line-height: 1.2;
  margin-bottom: 4px;
}

.stats-suffix {
  font-size: 16px;
  font-weight: 500;
  color: var(--n-text-color-2);
}

.stats-label {
  font-size: 14px;
  color: var(--n-text-color-2);
  margin-bottom: 8px;
}

.stats-change {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  font-weight: 500;
}

.stats-change.positive {
  color: #18a058;
}

.stats-change.negative {
  color: #d03050;
}

.stats-change.neutral {
  color: var(--n-text-color-3);
}

.stats-loading {
  position: absolute;
  top: 24px;
  right: 24px;
  left: 104px;
  bottom: 24px;
  background: var(--n-color-target);
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .stats-card {
    padding: 16px;
    gap: 12px;
  }
  
  .stats-icon {
    width: 48px;
    height: 48px;
  }
  
  .stats-value {
    font-size: 24px;
  }
  
  .stats-suffix {
    font-size: 14px;
  }
}
</style>
